package sicnu.cs.aps.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;
import sicnu.cs.aps.common.util.JwtUtil;
import sicnu.cs.aps.security.provider.EmailAuthenticationProvider;
import sicnu.cs.aps.security.rest.EmailAuthenticationFilter;
import sicnu.cs.aps.security.rest.RestAuthenticationFailureHandler;
import sicnu.cs.aps.security.rest.RestAuthenticationSuccessHandler;
import sicnu.cs.aps.service.impl.RedisService;

/**
 * @author CaiKe
 * @date 2021/11/10 18:17
 */

@Component
@RequiredArgsConstructor
public class SecurityEmailConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    private final UserDetailsService userDetailsService;
    private final JwtUtil jwtUtil;
    private final ObjectMapper objectMapper;
    private final RedisService redisService;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        var filter = new EmailAuthenticationFilter(objectMapper);
        filter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        filter.setAuthenticationSuccessHandler(new RestAuthenticationSuccessHandler(jwtUtil, objectMapper));
        filter.setAuthenticationFailureHandler(new RestAuthenticationFailureHandler(objectMapper));
        filter.setFilterProcessesUrl("/email/login");

        var provider = new EmailAuthenticationProvider(userDetailsService, redisService);

        http.authenticationProvider(provider)
                .addFilterAfter(filter, UsernamePasswordAuthenticationFilter.class);
    }
}